package com.jrew.gae.stacktracer;

import java.io.IOException;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang.StringEscapeUtils;

import com.google.appengine.api.datastore.Text;
import com.jrew.gae.stacktracer.constant.AppConstants;
import com.jrew.gae.stacktracer.entities.Record;
import com.jrew.gae.stacktracer.exceptions.RecordNotExistException;
import com.jrew.gae.stacktracer.exceptions.RecordWrongPasswordException;
import com.jrew.gae.stacktracer.services.RecordManagerService;

public class GetRecordServlet extends HttpServlet {
	
	/**
	 * 
	 */
	private static final long serialVersionUID = -7324590187627092160L;
	
	/**
	 * 
	 */
	private static final Logger logger = Logger.getLogger(GetRecordServlet.class.getName());
	
	/**
	 * 
	 */
	private RecordManagerService recordManagerService;
	
	/**
	 * 
	 */
	public GetRecordServlet() {
		recordManagerService = new RecordManagerService();
	}
	
	@Override
	protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}
	
	@Override
	protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
		processRequest(request, response);
	}
	
	/**
	 * @param request
	 * @param response
	 */
	private void processRequest(HttpServletRequest request, HttpServletResponse response){
		try{
			String recordId = request.getParameter(AppConstants.RECORD_ID);
			String recordPassword = request.getParameter(AppConstants.RECORD_PASSWORD);
			if(recordId != null && recordPassword != null){
				getRecord(request, response, Long.parseLong(recordId), recordPassword);
				return;
			} else {
				Long recordIdAttr = (Long) request.getAttribute(AppConstants.RECORD_ID);
				recordPassword = (String) request.getAttribute(AppConstants.RECORD_PASSWORD);
				if(recordIdAttr != null && recordPassword != null){
					getRecord(request, response, recordIdAttr, recordPassword);
					return;
				}
			}
			forwardToAddRecordPage(request, response);
		} catch (Exception e) {
			e.printStackTrace();
			forwardToAddRecordPage(request, response);
		}
	}
	
	/**
	 * @param request
	 * @param response
	 * @param id
	 */
	private void getRecord(HttpServletRequest request, HttpServletResponse response, long id, String password){
		try{
			Record record = recordManagerService.getRecord(id, password);
			Text recordContent = record.getContent();
			String escapedRecordContent = StringEscapeUtils.escapeXml(recordContent.getValue());
			request.setAttribute(AppConstants.RECORD_CONTENT, escapedRecordContent);
			request.setAttribute(AppConstants.LINK_ATTRIBUTE, createLinkOnRecord(request, id, password));
			request.getRequestDispatcher(AppConstants.GET_RECORD_JSP_PATH).forward(request, response);
		} catch (RecordNotExistException e) {
			logger.log(Level.WARNING, "Trying to fetch non exist record");
			forwardToAddRecordPage(request, response);
		} catch (RecordWrongPasswordException e) {
			logger.log(Level.WARNING, "Trying to fetch record with wrong password");
			forwardToAddRecordPage(request, response);
		} catch (Exception e) {
			logger.log(Level.WARNING, "Can't dispath to ger record jsp.");
			forwardToAddRecordPage(request, response);
		}
	}
	
	/**
	 * @param request
	 * @param response
	 */
	private void forwardToAddRecordPage(HttpServletRequest request, HttpServletResponse response){
		try{
			RequestDispatcher requestDispatcher = request.getRequestDispatcher(AppConstants.ADD_RECORD_JSP_PATH);
			requestDispatcher.forward(request, response);
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * @param request
	 * @param recordId
	 * @return
	 */
	private String createLinkOnRecord(HttpServletRequest request, Long recordId, String password){
		String url = request.getRequestURL().toString() + "?" + 
					 AppConstants.RECORD_ID + "=" + recordId + "&" + 
					 AppConstants.RECORD_PASSWORD + "=" + password; 
		return url;
	}
}
